#include "stdio.h"
#include<conio.h>
#include<stdlib.h>
#define getjcb(type) (type*)malloc(sizeof(type))
#define NULL 0
int n=0,time=0;float eti,ewi;
struct jcb
{   
    char name[10]; /* 作业名 */
    char state; /* 作业状态 */
    int ts; /* 提交时间 */
    int tb; /* 开始运行时间 */
    int tc; /* 完成时间 */
    float ti; /* 周转时间 */
    float wi; /* 带权周转时间 */
    int ntime; /* 作业所需运行时间 */
    int priority; /* 优先级 */
    struct jcb *link; /* 结构体指针 */
} *p,*q,*head=NULL;
typedef struct jcb JCB;
initial(){
    int i;
    printf("\nInput jcb num\n");
    scanf("%d",&n);
    printf("Input\nname\tts\tntime\tpriority\n");
    for(i=0;i<n;i++){
        p=getjcb(JCB);
        scanf("%s\t%d\t%d\t%d",&p->name,&p->ts,&p->ntime,&p->priority);
        p->state='W';
        p->link=NULL;
        if(head==NULL) head=q=p;
        else{
            q->link=p;
            q=p;
    }
}
}
void print(JCB *pr){
    JCB *p;
    printf("\ntime=%d",time);
    printf("\nname\tstate\tts\tntime\priority\ttb\ttc\tti\twi\n");
    printf("%s\t%c\t%d\t%d\t%d\t%d\t%d\t%4.2f\t%4.2f\n",
    pr->name,pr->state,pr->ts,pr->ntime,pr->priority,pr->tb,pr->tc,pr->ti,pr->wi);
    p=head;
    do{
        if(p->state=='W')
        printf("%s\t%c\t%d\t%d\t%d\n",
        p->name,p->state,p->ts,p->ntime,p->priority);
        p=p->link;
}while(p!=NULL);
 p=head;
 do{
    if(p->state=='F')
    printf("%s\t%c\t%d\t%d\t%d\t%d\t%d\t%4.2f\t%4.2f\n",
    p->name,p->state,p->ts,p->ntime,p->priority,p->tb,p->tc,p->ti,p->wi);
    p=p->link;
 }while(p!=NULL);
}
void last(){
    eti/=n;ewi/=n;
    printf("\neti=%7.3f\tewi=%7.3f\n",eti,ewi);
}
running(JCB *p){
 p->tb=time;p->state='R';
 p->tc=p->tb+p->ntime;
 p->ti=(float)(p->tc-p->ts);
 p->wi=(float)(p->ti/p->ntime);
 eti+=p->ti;
 ewi+=p->wi;
 print(p);
 time+=p->ntime;
 p->state='F';
 printf("\n%s has been finished!\npress any key to continue...\n",p->name);
 getch();
}
void sjf(){
    JCB *min;
    int i,iden;
    for(i=0;i<n;i++){
        p=min=head;iden=1;
        do{
            if(p->state=='W'&&p->ts<=time)
            if(iden){
                min=p;iden=0;
            }
            else if(p->ntime<min->ntime) min=p;
            p=p->link;
        }while(p!=NULL) ;
        if(iden) {
            i--;printf("\ntime=%d:\tno JCB submib...wait...",time);time++;
            if(time>100){printf("\nruntime is too long...error");getch();}
        }
        else{
            running(min);
        }
    }
}
fcfs(){
 JCB *min;
 int i,iden;
 for(i=0;i<n;i++){
p=min=head;iden=1;
do{
 if(p->state=='W'&&p->ts<=time)
if(iden){
min=p;iden=0;
 }
else if(p->ts<min->ts) min=p;
 p=p->link;
}while(p!=NULL) ;
 
if(iden) {
 i--;printf("\ntime=%d:\tno JCB submib...wait...",time);time++;
 if(time>100){printf("\nruntime is too long...error");getch();}
 }
else{
 running(min);
}
 }
}
fpf()
{
    JCB *min;
    int i,iden;
    for(i=0;i<n;i++){
        p=min=head;iden=1;
        do{
            if(p->state=='W'&&p->ts<=time)
            if(iden){
                min=p;iden=0;
            }
            else if(p->priority>min->priority) min=p;
            p=p->link;
        }while(p!=NULL) ;
        if(iden) {
            i--;printf("\ntime=%d:\tno JCB submib...wait...",time);time++;
            if(time>100){printf("\nruntime is too long...error");getch();}
        }
        else{
            running(min);
        }
    }
}
void runjcb(int m){
 printf("\n\nstart running jcb use algorithm %d.",m);
 switch(m){
case 1:fcfs();break;
case 2:sjf();break;
case 3:fpf();break;
default:printf("\nrunjcb error...\n");
exit(0);
 }
}
start(){
 int m;
 char str[100]="\nselect algorithm\n1.FCFS\n2.SJF\n3.FPF\n" ;
 printf("%s",str);
 m=getch()-48;
 initial();
 if(1<=m&&m<=3) runjcb(m);
 else {
printf("\nselect error!try again...\n");
start();
 }
 last();
}
main(){
start();
 printf("\nfinished!");
 getch();
}